import { useEffect } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as CANNON from "cannon-es";

import { CannonEsDebuggerPro } from "@vladkrutenyuk/cannon-es-debugger-pro";
function App() {
    useEffect(() => {
        // 创建世界
        const scene = new THREE.Scene();
        // 创建相机
        const camera = new THREE.PerspectiveCamera(
            75,
            window.innerWidth / window.innerHeight,
            0.1,
            1000
        );
        // 设置相机位置
        camera.position.z = 20;
        camera.position.x = 0;
        camera.position.y = 10;
        camera.lookAt(0, 20, 0); // 设置相机朝向

        const root = new THREE.Group();
        scene.add(root); // 将根节点添加到场景中

        // 创建两个数组更新物理世界和threejs世界
        const cannonBodies = [];
        const threeObjects = [];

        // 创建物理世界
        const world = new CANNON.World();
        // 允许休眠
        world.allowSleep = true;

        const color = 0xe60c0c; // or 'rgb(228, 14, 88)', '#e60c0c', 'red'
        const offset = 0.009;
        const cannonDebugger = new CannonEsDebuggerPro(root, world, color, offset);


        {
            // 设置重力
            world.gravity.set(0, -9.82, 0); // m/s²

            // 创建SPH流体系统
            const sphSystem = new CANNON.SPHSystem()
            // 设置流体的密度和粘度
            sphSystem.density = 1; // kg/m³
            sphSystem.viscosity = 0.1; // Pa.s
            // 设置流体交互距离
            sphSystem.interactionDistance = 1; // m
            world.subsystems.push(sphSystem); // 将流体系统添加到物理世界中


            {
                const boxShape = new CANNON.Particle();

                // 创建threejs物体
                const geometry = new THREE.SphereGeometry(0.1, 32, 32);
                const material = new THREE.MeshBasicMaterial({
                    color: 0xffffff,
                });


                for (let i = 0; i < 400; i++) {
                    const boxBody = new CANNON.Body({
                        mass: 0.01, // 质量
                        shape: boxShape, // 物体形状
                        position: new CANNON.Vec3(
                            Math.random() - 0.5,
                            10 + i,
                            Math.random() - 0.5,
                        ) // 初始位置
                    });
                    world.addBody(boxBody);
                    sphSystem.add(boxBody); // 将物体添加到流体系统中

                    cannonBodies.push(boxBody);


                    const mesh = new THREE.Mesh(geometry, material);
                    root.add(mesh); // 将物体添加到场景中

                    // 将物理世界和threejs世界的物体添加到数组中
                    threeObjects.push(mesh);

                }

            }

            // 添加地面
            {
                // 创建平面
                const planeShape = new CANNON.Plane();
                const planeBody = new CANNON.Body({
                    mass: 0, // 质量为0表示静止物体
                    position: new CANNON.Vec3(0, 0, 0), // 初始位置
                });
                // 设置平面的旋转
                planeBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0); // 绕x轴旋转90度
                planeBody.addShape(planeShape);
                world.addBody(planeBody);
            }
        }

        {

            {
                // 创建平面
                const planeShape = new THREE.BoxGeometry(10, 0.1, 10);
                const planeMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff });
                const plane = new THREE.Mesh(planeShape, planeMaterial);
                // 设置平面位置
                plane.position.y = -0.1;
                // 将平面添加到场景中
                // scene.add(plane);
            }
        }

        // 创建渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        // 将渲染器添加到DOM中
        document.getElementById("app").appendChild(renderer.domElement);

        // 添加轨道控制器
        const controls = new OrbitControls(camera, renderer.domElement);
        // 创建坐标辅助器
        const axesHelper = new THREE.AxesHelper(5);
        scene.add(axesHelper); // 将坐标辅助器添加到场景中

        // 创建动画函数
        const animate = function () {
            // 更新物理世界
            world.step(1 / 60); // 60fps
            // 更新threejs世界
            for (let i = 0; i < cannonBodies.length; i++) {
                const body = cannonBodies[i];
                const mesh = threeObjects[i];
                // 更新threejs物体的位置和旋转
                mesh.position.copy(body.position);
                mesh.quaternion.copy(body.quaternion);
            }
            cannonDebugger.update(); // 更新调试器

            // 更新轨道控制器
            controls.update();

            requestAnimationFrame(animate);

            // 渲染场景
            renderer.render(scene, camera);
        };
        // 调用动画函数
        animate();

        return () => {
            // 清除渲染器
            renderer.dispose();
            // 清除场景
            scene.clear();
            // 清除相机
            camera.clear();
            // 清除渲染器DOM
            const app = document.getElementById("app");
            if (app) {
                app.removeChild(renderer.domElement);
            }
        };
    }, []);
    return <div id="app"></div>;
}

export default App;
